/********************************************************************************
 * Project Name		[JavaEE_Web]
 * File Name     	[Servlet05.java]
 * Creation Date 	[2015-01-01]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ********************************************************************************/
package _notes.servlet;

/**
 * 过滤器
 * 
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 * 
 */
public final class Servlet05 {

	public void filterConcept() {
		/**
		 * Filter的基本功能<br/>
		 * 对Web容器调用Servlet/JSP的请求进行拦截, 从而在Servlet/JSP进行响应处理的前后实现一些特殊的功能<br/>
		 * 
		 * Filter程序是一个实现了Filter接口的Java类, 与Servlet程序相似, 它由Servlet容器进行调用和执行<br/>
		 * Filter程序需要在web.xml文件中进行注册和设置它所能拦截的资源<br/>
		 * Filter程序可以拦截 Jsp, Servlet, 静态图片文件和静态html文件<br/>
		 * Filter程序并不依赖于具体的协议<br/>
		 * 
		 * Filter的API<br/>
		 * Filter<br/>
		 * FilterChain<br/>
		 * FilterConfig<br/>
		 */

		/**
		 * Filter的工作原理<br/>
		 * 1. Filter是Servlet容器与Servlet/JSP程序通信线路上的一道关卡<br/>
		 * 2. Filter可以对发送给Servlet/JSP程序的请求和Servlet/JSP程序回送的响应进行拦截<br/>
		 * 3. Filter可以决定是否将请求继续传递给Servlet/JSP程序, 以及对请求和响应信息是否进行修改等操作<br/>
		 * 
		 * 注意<br/>
		 * 1. 一个Web应用程序中可以注册多个Filter程序, 每个Filter程序都可以对一个或一组Servlet/JSP程序进行拦截
		 * <br/>
		 * 2. 若有多个Filter对某个Servlet/JSP程序的访问过程进行拦截, 当针对该Servlet/JSP的访问请求到达时,
		 * Web容器将把这几个Filter程序组合成一个FilterChain<br/>
		 * 3. FilterChain中各个Filter的拦截顺序与它们在web.xml中<filter-mapping>配置的顺序一致<br/>
		 * 使用注解的Filter则根据FilterName决定顺序<br/>
		 */
	}

	public void filterXmlConfiguration() {
		/**
		 * Filter的web.xml配置<br/>
		 * 
		 * <code>
		 * <filter>
		 *     <filter-name>HelloWorldFilter</filter-name>
		 *     <filter-class>filter.HelloWorldFilter</filter-class>
		 *     <init-param>
		 *         <param-name>name</param-name>
		 *         <param-value>user</param-value>
		 *     </init-param>
		 * </filter>
		 * 
		 * <filter-mapping>
		 *     <filter-name>HelloWorldFilter</filter-name>
		 *     <url-pattern>*.jsp</url-pattern>					<!-- 指定对所有JSP进行拦截 -->
		 *     <servlet-name></servlet-name>					<!-- 指定被拦截的Servlet, 和<url-pattern>二选一-->
		 *     <dispatcher>REQUEST</dispatcher>					<!-- 指定过滤器所拦截的资源被Servlet容器调用的方式, 可选 -->
		 * </filter-mapping>
		 * </code><br/>
		 * 
		 * <dispatcher>指定过滤器所拦截的资源被Servlet容器调用的方式<br/>
		 * 可取值[REQUEST | INCLUDE | FORWARD | ERROR]之一, 默认值: REQUEST<br/>
		 * 可以设置多个<dispatcher>子元素用来指定Filter对资源的多种调用方式进行拦截<br/>
		 * 
		 * REQUEST: <br/>
		 * 1. 当用户直接访问页面时, Web容器将会调用过滤器<br/>
		 * 2. 如果目标资源是通过RequestDispatcher的include()或forward()方法访问则该过滤器不会被调用 <br/>
		 * 
		 * INCLUDE: <br/>
		 * 1. 如果目标资源是通过RequestDispatcher的include()方法访问时, 该过滤器将被调用<br/>
		 * 2. 如果目标资源是通过<jsp:include page="/...">访问时, 该过滤器将被调用<br/>
		 * 3. 除此之外, 该过滤器不会被调用<br/>
		 * 
		 * FORWARD: <br/>
		 * 1. 如果目标资源是通过RequestDispatcher的forward()方法访问时, 该过滤器将被调用<br/>
		 * 2. 如果目标资源是通过<jsp:forward page="/...">访问时, 该过滤器将被调用<br/>
		 * 3. 通过page指令的errorPage转发页面<%@ page errorPage="error.jsp" %>, 该过滤器将被调用
		 * <br/>
		 * 4. 除此之外, 该过滤器不会被调用<br/>
		 * 
		 * ERROR: <br/>
		 * 1. 如果目标资源是通过声明式异常处理机制[在web.xml中配置的错误处理, 见下例]调用时, 该过滤器将被调用<br/>
		 * 2. 除此之外, 该过滤器不会被调用<br/>
		 * <code>
		 * <error-page>
		 *     <exception-type>java.lang.ArithmeticException</exception-type>	<!-- 指定异常的类型 -->
		 *     <location>/WEB-INF/error.jsp</location>							<!-- 指定响应页面的位置 -->
		 * </error-page>
		 * </code>
		 */
	}

	public void filterAnnotationConfiguration() {
		/**
		 * Filter的注解配置<br/>
		 * <code>
		 * <pre>@WebFilter(
		 *          filterName = "HelloWorldFilter", 
		 *          urlPatterns = "*.jsp", 
		 *          initParams = { @WebInitParam(name = "characterEncoding", value = "UTF-8") }
		 *          dispatcherTypes = { DispatcherType.REQUEST })
		 * </pre>
		 * </code>
		 */
	}

	public void filterAPI() {
		/**
		 * Filter接口<br/>
		 * 
		 * init(FilterConfig config): 类似于Servlet的init()方法, 在创建Filter对象后立即被调用,
		 * 且只被调用一次. 该方法用于对当前的Filter进行初始化<br/>
		 * 1. Filter对象在Servlet容器加载当前Web应用时即被创建<br/>
		 * 2. Filter对象是单例的<br/>
		 * 
		 * doFilter(ServletRequest request, ServletResponse response,
		 * FilterChain chain): 真正的逻辑代码所在方法, 每次拦截都会调用该方法<br/>
		 * 1. 类似于Servlet接口的service()方法<br/>
		 * 2. 当前Filter把请求传递给FilterChain的下一个Filter,
		 * 如果当前Filter是FilterChain的最后一个Filter, 则把请求转交给Servlet/JSP<br/>
		 * 
		 * destroy(): 释放当前Filter所占用的资源, 在Filter被销毁或服务器停止前被调用, 只调用一次<br/>
		 */

		/**
		 * FilterConfig接口<br/>
		 * 
		 * FilterConfig接口类似于ServletConfig接口, 可以配置初始化参数<br/>
		 * FilterConfig对象可以得到ServletContext对象, 以及web.xml中配置的过滤器的初始化参数<br/>
		 * 
		 * 方法<br/>
		 * getFilterName(): 得到描述符中指定的过滤器的名字<br/>
		 * getInitParameter(String name): 得到在过滤器的指定初始化参数名称的参数值, 果不存在返回null<br/>
		 * Enumeration getInitParameterNames(): 得到过滤器的所有初始化参数的名字的枚举集合<br/>
		 * getServletContext(): 得到ServletContext对象的引用<br/>
		 */

		/**
		 * FilterChain接口<br/>
		 * 
		 * 代表当前 Filter链的对象, 由容器实现<br/>
		 * 过滤器对象使用FilterChain对象调用过滤器链中的下一个过滤器, 如果该过滤器是链中最后一个过滤器, 那么将调用目标资源<br/>
		 */
	}
}
